本次学习内容:Spring AOP相关
问题引入
1 2 3 4 5 6
| public class User { public void addUser() { } }
|
—— 需求,在上面原有的功能中,加入用户日志,记录用户信息?如何做?
—— 方法尝试:
1 2 3 4 5 6
| public class BaseUser { public void writeLog() { } }
|
1 2 3 4 5 6 7
| public class User extends BaseUser{ public void addUser() { super.writeLog(); } }
|
这种 纵向 的抽取,并不能友好的解决问题,一旦父类的名称改变,后面也要接着更改
AOP 原理
有接口
1 2 3 4 5 6 7 8 9 10 11
| public interface Dao { void add(); } public class DaoImpl implements Dao { public void add() { } }
|
使用 jdk 动态代理,生成 接口实现类的代理对象,来增相应方法的功能
没有接口
1 2 3 4 5
| public class User { public void addUser() { } }
|
使用 cglib 动态代理,生成其子类的代理对象,调用父类的方法,来增强相应功能
几个重要 术语
- 连接点 JoinPoint:类中哪些方法可以被 增强,这些方法就是 连接点
- 切入点 PointCut:类中实际增强类那些方法(如:add,update),这些方法称为 切入点
- 通知/增强 advice: 增强的逻辑,如:要扩展日志功能,则日志功能为 增强/通知
分为:前置通知(方法之前执行),后置通知,异常通知(方法出现异常),最终通知(后置之后执行),环绕通知(方法之前和之后执行)
- 切面 aspect:把增强功能应用到具体方法上,这个过程叫切面。即:把增强应用到切入点的过程
- 目标对象 target: 要增强的类,代理的目标对象
- 织入 weaving: 把增强应用到目标的过程,把advice 应用到target的过程
- 代理 Proxy: 一个类被aop织入增强后,就产生一个结果代理类
实现AOP
xml 配置实现
切入点配置表达式:
execution(<访问修饰符> <返回类型><方法名>(参数)<异常>)
e.g.
execution(* com.gjr.aop.Book.add(..))
execution(* com.gjr.aop.Book.*(..)) book 类下的所有方法加强
execution(* *.*(..)) 所有类下的所有方法加强
execution(* xxx*(..)) 所有xxx开头的方法加强
demo 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Book { public void show() { System.out.println("show book ...."); } } public class MyBook { public void addFunctionBefore() { System.out.println("在前面,加点功能 。。。"); } public void addFunctionAfter() { System.out.println("在后面,加点功能 。。。"); } public void arroundFunction(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("之前环绕 。。。"); proceedingJoinPoint.proceed(); System.out.println("之后环绕 。。。"); } }
|
xml配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="book" class="com.gjr.aspect.Book"/> <bean id="myBook" class="com.gjr.aspect.MyBook"/> <aop:config> <!-- 切点: 需要被增强功能的方法 --> <aop:pointcut id="bookPoint" expression="execution(* com.gjr.aspect.Book.show(..))"/> <aop:aspect ref="myBook"> <aop:before method="addFunctionBefore" pointcut-ref="bookPoint"/> <aop:after method="addFunctionAfter" pointcut-ref="bookPoint"/> <aop:around method="arroundFunction" pointcut-ref="bookPoint"/> </aop:aspect> </aop:config> </beans>
|
3种 切面类型同时存在时:before最先调用,after最后调用
注解实现 aop(只列出@Before,其他的相同)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Order { public void show() { System.out.println("show order ..."); } } @Aspect public class MyOrder { @Before(value = "execution(* Order.show(..))") public void addFunction() { System.out.println("add function ..."); } }
|
1 2 3 4 5
| <bean id="order" class="com.gjr.annaop.Order"/> <bean id="myOrder" class="com.gjr.annaop.MyOrder"/> <aop:aspectj-autoproxy/>
|
Spring 相关的 pom 配置
GroupId |
ArtifactId |
Description |
org.springframework |
spring-aop |
Proxy-based AOP support |
org.springframework |
spring-aspects |
AspectJ based aspects |
org.springframework |
spring-beans |
Beans support, including Groovy |
org.springframework |
spring-context |
Application context runtime, including scheduling and remoting abstractions |
org.springframework |
spring-context-support |
Support classes for integrating common third-party libraries into a Spring application context |
org.springframework |
spring-core |
Core utilities, used by many other Spring modules |
org.springframework |
spring-expression |
Spring Expression Language (SpEL) |
org.springframework |
spring-instrument |
Instrumentation agent for JVM bootstrapping |
org.springframework |
spring-instrument-tomcat |
Instrumentation agent for Tomcat |
org.springframework |
spring-jdbc |
JDBC support package, including DataSource setup and JDBC access support |
org.springframework |
spring-jms |
JMS support package, including helper classes to send and receive JMS messages |
org.springframework |
spring-messaging |
Support for messaging architectures and protocols |
org.springframework |
spring-orm |
Object/Relational Mapping, including JPA and Hibernate support |
org.springframework |
spring-oxm |
Object/XML Mapping |
org.springframework |
spring-test |
Support for unit testing and integration testing Spring components |
org.springframework |
spring-tx |
Transaction infrastructure, including DAO support and JCA integration |
org.springframework |
spring-web |
Web support packages, including client and web remoting |
org.springframework |
spring-webmvc |
REST Web Services and model-view-controller implementation for web applications |
org.springframework |
spring-webmvc-portlet |
MVC implementation to be used in a Portlet environment |
org.springframework |
spring-websocket |
WebSocket and SockJS implementations, including STOMP support |
附录
demo 地址:
https://github.com/fenglincanyi/springdemo2